feat(kmip): add token and AWS enrollment for KMIP server#254
Conversation
Adds --enroll-method=token|aws to 'kmip start' and 'kmip systemd install', persisting and reusing the enrollment access token, alongside the existing machine-identity flow.
|
💬 Discussion in Slack: #pr-review-cli-254-feat-kmip-add-token-and-aws-enrollment-for-kmip-server Posted by Review Police — reviews, comments, new commits, and CI failures will stream into this channel. |
|
| Filename | Overview |
|---|---|
| packages/cmd/kmip.go | Core command handler for kmip start and kmip systemd install; adds token/AWS enrollment flows with a logic hole (fallthrough to re-enrollment with an already-spent token) and unvalidated domain used as the API endpoint. |
| packages/kmip/enroll.go | New file: key/value config store for enrollment state (access token, enrollment token, server ID, domain) at ~/.infisical/kmip/<name>.conf or /etc/infisical/kmip/<name>.conf; file permissions are 0600, logic is correct. |
| packages/kmip/aws_auth.go | New file: signs a presigned STS GetCallerIdentity request and forwards its headers to Infisical for AWS Auth enrollment; standard pattern, no actual outbound STS call is made. |
| packages/kmip/systemd.go | Refactored into helpers (kmipCommonEnv, writeKmipSystemdService, systemdPreconditionsMet) and two new installers for token/AWS methods; env-file values are not sanitized against newline injection. |
| packages/api/api.go | Adds CallKmipServerLogin following the same pattern as adjacent API calls; no issues found. |
| packages/api/model.go | Adds KmipServerLoginRequest and KmipServerLoginResponse structs; straightforward, no issues. |
Reviews (1): Last reviewed commit: "feat(kmip): add token and AWS enrollment..." | Re-trigger Greptile
| payloadHash := fmt.Sprintf("%x", hash.Sum(nil)) | ||
|
|
||
| signer := v4.NewSigner() | ||
| if err := signer.SignHTTP(ctx, awsCredentials, req, payloadHash, "sts", awsRegion, time.Now()); err != nil { |
There was a problem hiding this comment.
Medium: AWS enrollment proof is replayable
The SigV4 request only proves the AWS principal; kmipServerID is sent later as unsigned JSON. Anyone who obtains this enrollment payload can replay the same iamRequestBody and iamRequestHeaders with a different kmipServerId during the SigV4 validity window, authenticating this host to any KMIP server configuration that trusts the same AWS principal. Add a custom audience header containing the KMIP server ID before SignHTTP, forward it in IamRequestHeaders, and have the API verify that the signed header matches the JSON kmipServerId.
PR overviewThis pull request adds token-based and AWS IAM-based enrollment support for a KMIP server, including AWS authentication request construction in the KMIP package. One security issue remains open after one prior issue was addressed. The remaining concern is that the AWS enrollment proof binds only to the AWS principal and not to the target KMIP server ID, allowing a captured enrollment payload to be replayed against another trusted KMIP server configuration during the SigV4 validity window. Binding the KMIP server ID into the signed AWS request would close this replay path. Open issues (1)
Fixed/addressed: 1 · PR risk: 6/10 |
Picks up the published release with the AccessToken field, so the CLI builds without the local replace directive.
For enrollment-based KMIP servers the cert config (hostnames/IPs, TTL, common name, key algorithm) is configured in the UI and read by the daemon via /kmip/servers/connect, so --hostnames-or-ips is no longer required at launch.
infisical kmip start/systemd install now take <server-name> as a positional argument, e.g. 'infisical kmip start my-server'. The --server-name flag and INFISICAL_KMIP_SERVER_NAME env var still work as alternatives; the name is required (no longer defaults to kmip-server).
Picks up the /kmip/servers/connect daemon path so enrollment-based KMIP servers fetch their certificate from the platform instead of passing cert config at launch.
The e2e module (replace infisical-merge => ../) still pinned infisical-kmip v0.3.17 as an indirect dep, which left it un-tidy and failed the E2E 'go test' tidy check. Re-tidied to v0.3.19 to match the root module.
| if err := localkmip.InstallEnrolledKmipSystemdService(enrollResp.AccessToken, domain, listenAddress, serverName, certificateTTL, hostnamesOrIps); err != nil { | ||
| util.HandleError(err, "Failed to install systemd service") | ||
| } | ||
| case localkmip.EnrollMethodAws: |
There was a problem hiding this comment.
mmm is it intended that AWS does no auth validation at install time? 🤔
There was a problem hiding this comment.
Yea this is the same way the gateway/relay do it
…egacy auth When no enroll method is given, reuse the stored enrollment access token unless explicit identity credentials were passed, rather than silently dropping to legacy machine-identity auth. Mirrors the gateway's start behavior. Token systemd installs rely on this fallback (the long-lived token is reused); the AWS path still persists the method to force STS re-auth.
78972af to
87255b7
Compare
Both 'kmip start' and 'kmip systemd install' resolved + validated --enroll-method with the same flag/env/validate block. Unify into resolveEnrollMethod (per review feedback).
Both commands resolved the Infisical domain differently (start: flag -> stored -> logged-in; install: flag -> env). Extract one resolveDomain helper (flag -> stored -> logged-in -> env) used by both, per review feedback. Behavior preserved: stored/logged-in are empty at a fresh install so it stays flag -> env there, and env remains lowest priority at start.
… install Both now read "Domain of your self-hosted Infisical instance", matching each other and the gateway/relay flag wording.
Description 📣
Adds
--enroll-method=token|awstoinfisical kmip startandkmip systemd install, so a KMIP server enrolls with a one-time token or AWS auth and reuses the derived access token across restarts; the legacy--identity-client-id/secretflow still works. Depends on a newinfisical-kmiprelease —go.modis still pinned tov0.3.17and must be bumped before merge (currently builds via a localreplace).Type ✨
Tests 🛠️
Manually enrolled a KMIP server via token and AWS (including
systemd install) against a local backend, verified registration and a real KMIP crypto op, and confirmed the legacy machine-identity flow still registers.